<?php

namespace app\libs;

/**
 * 通用工具处理
 * Class Util
 * @package app\libs
 */
class Util
{
    /**
     * 数据格式化
     * @param $data
     * @return mixed
     */
    public static function numberFormat($data)
    {
        foreach ($data as $key => $value) {
            if (floatval($data[$key]) > 9999 || floatval($data[$key]) < -9999) {
                $data[$key] = round($data[$key] / 10000, 2) . "W";
            }
        }
        return $data;
    }

    /**
     * 获取客户端真实的ip
     * @return bool|mixed
     */
    public static function get_real_ip()
    {
        $ip = FALSE;
        //客户端IP 或 NONE
        if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
            $ip = $_SERVER["HTTP_CLIENT_IP"];
        }
        //多重代理服务器下的客户端真实IP地址（可能伪造）,如果没有使用代理，此字段为空
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ips = explode(", ", $_SERVER['HTTP_X_FORWARDED_FOR']);
            if ($ip) {
                array_unshift($ips, $ip);
                $ip = FALSE;
            }
            for ($i = 0; $i < count($ips); $i++) {
                if (!preg_match("^(10│172.16│192.168).", $ips[$i])) {
                    $ip = $ips[$i];
                    break;
                }
            }
        }
        //客户端IP 或 (最后一个)代理服务器 IP
        return ($ip ? $ip : $_SERVER['REMOTE_ADDR']);
    }

    /**
     * 数组层级缩进转换-父子包含
     * @param $list
     * @param $p_id
     * @return array
     */
    public static function levelTreeChildren($list, $p_id)
    {
        $r = array();
        foreach ($list as $id => $item) {
            if ($item['parent_id'] == $p_id) {
                $length = count($r);
                $r[$length] = $item;
                if ($t = self::levelTreeChildren($list, $item['id'])) {
                    $r[$length]['children'] = $t;
                }
            }
        }
        return $r;
    }

    /**
     * 对二维数组进行排序
     * 模拟 数据表记录按字段排序
     * @param array $array 要排序的数组
     * @param string $orderKey 排序关键字/字段
     * @param string $orderType 排序方式，'asc':升序，'desc':降序
     * @param string $orderValueType 排序字段值类型，'number':数字，'string':字符串
     */
    public static function listOrder(&$array, $orderKey, $orderType = 'asc', $orderValueType = 'string')
    {
        if (is_array($array)) {
            $orderArr = array();
            foreach ($array as $val) {
                $orderArr[] = $val[$orderKey];
            }
            $orderType = ($orderType == 'asc') ? SORT_ASC : SORT_DESC;
            $orderValueType = ($orderValueType == 'string') ? SORT_STRING : SORT_NUMERIC;
            array_multisort($orderArr, $orderType, $orderValueType, $array);
        }
    }

    /**
     * 获取全部子集以及制定字段
     * @param $list
     * @param string $field
     * @return array
     */
    public static function getChildrenIds($list, $field = "id")
    {
        $ids = [];
        foreach ($list as $key => $value) {
            $ids_temp = [];
            $ids_temp = Util::getChildrenId($value, $ids_temp, $field);
            if (empty($ids_temp)) {
                $ids[$key]['title'] = $value['name'];
                $ids[$key]['ids'] = $ids_temp;
                $ids[$key]['ids_str'] = $value['id'];
            } else {
                $ids_temp[] = $value['id'];
                $ids[$key]['title'] = $value['name'];
                $ids[$key]['ids'] = $ids_temp;
                $ids[$key]['ids_str'] = implode(',', $ids_temp);
            }
        }
        return $ids;
    }

    /**
     * 获取单条子集制定字段数组
     * @param $list
     * @param array $ids
     * @param string $field
     * @return array
     */
    public static function getChildrenId($list, &$ids, $field = "id")
    {
        if (empty($list['children'])) {
            return $ids;
        }
        foreach ($list['children'] as $value) {
            $ids[] = $value[$field];
            if (!empty($value['children'])) {
                Util::getChildrenId($value, $ids);
            }
        }
        return $ids;
    }

    /**
     * GET请求
     * @param $url
     * @return bool|string
     */
    public static function httpGet($url)
    {
        $url = str_replace('&amp;', '&', $url);
        $options = array(
            'http' => array(
                'method' => 'GET',
                'timeout' => 10
            )
        );
        $context = stream_context_create($options);
        $data = @file_get_contents($url, false, $context);
        return $data;
    }


    /**
     * 商品属性转换
     * @param $data 商品数据
     * @return array
     */
    public static function goodsDataSwitch($data)
    {
        $data['goods_up_count'] = $data['goods_up_count'] > 9999 ? "9999+" : $data['goods_up_count'];//点赞
        $data['goods_share_count'] = $data['goods_share_count'] > 9999 ? ($data['goods_share_count'] / 10000) . "万" : $data['goods_share_count'];//分享数
        $data['goods_collect_count'] = $data['goods_collect_count'] > 9999 ? "9999+" : $data['goods_collect_count'];
        $data['goods_read_count'] = $data['goods_read_count'] > 9999 ? ($data['goods_read_count'] / 10000) . "万" : $data['goods_read_count'];//分享
        if (!empty($data['goods_photo'])) {
            $data['goods_photo'] = explode(",", $data['goods_photo']);//相册转换
        }
        if (!empty($data['goods_detail'])) {
            $data['goods_detail'] = explode(",", $data['goods_detail']);//详情转换
        }
        $data['goods_top_money'] = round(floatval($data['goods_top_money']) * floatval($data['goods_min_price']), 2);
        $data['goods_return_money'] = round(floatval($data['goods_return_money']) * floatval($data['goods_min_price']), 2);
        $goods_tag = [];
        if (!empty($data['goods_tag'])) {
            if (strpos($data['goods_tag'], '、') > 0) {
                $goods_tag = explode('、', $data['goods_tag']);
            } else {
                $goods_tag[] = $data['goods_tag'];
            }
        }
        $data['goods_tag'] = $goods_tag;
        $data['goods_parameter_str'] = "";
        if (!empty($data['goods_parameter'])) {
            $data['goods_parameter'] = json_decode($data['goods_parameter'], true);
            foreach ($data['goods_parameter'] as $value) {
                $data['goods_parameter_str'] .= $value['name'] . " ";
            }
        }
        if (intval($data['goods_reserve']) == 1) {
            $data['goods_reserve_send_str'] = date("Y-m-d", $data['goods_reserve_send']);
        }
        return $data;
    }


    /**
     * 商品发现属性转换
     * @param $data 商品数据
     * @return array
     */
    public static function goodsFindDataSwitch($data)
    {
        $data['up_count'] = $data['up_count'] > 9999 ? "9999+" : $data['up_count'];//点赞
        $data['read_count'] = $data['read_count'] > 10000 ? round($data['read_count'] / 10000, 2) . "万" : $data['read_count'];//分享数
        $data['collect_count'] = $data['collect_count'] > 9999 ? "9999+" : $data['collect_count'];
        $data['photo'] = explode(",", $data['photo']);//相册转换
        return $data;
    }

    /**
     * post请求
     * @param url 请求url
     * @param post_data 请求数据
     **/
    public static function post_request($url = "", $post_data = "")
    {
        //初始化
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;
    }

    /**
     * get请求
     * @param string $url
     * @param array $post_data
     * @return false|string
     */
    public static function get_request($url = "", $post_data = [])
    {
        //初始化
        $par = "";
        foreach ($post_data as $key => $value) {
            $par .= "&" . $key . "=" . $value;
        }
        $par = substr($par, 1, strlen($par));
        $data = file_get_contents($url . "?" . $par);
        return $data;
    }


    //根据jscode 获取openid
    public static function get_openid_jscode($post_data)
    {
        $url = "https://api.weixin.qq.com/sns/jscode2session";//微信登录地址
        $urls = $url . "?appid=" . $post_data['appid'] . "&secret=" . $post_data['secret'] . "&js_code=" . $post_data['js_code'] . "&grant_type=" . $post_data['grant_type'];
        $data = file_get_contents($urls);
        return $data;
    }

    /**
     * post 微信api带证书请求
     * @param url 请求url
     * @param post_data 请求数据
     **/
    public static function post_request_ssl($url = "", $post_data = "")
    {
        $ch = curl_init();
        $params[CURLOPT_URL] = $url;    //请求url地址
        $params[CURLOPT_HEADER] = false; //是否返回响应头信息
        $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回
        $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向
        $params[CURLOPT_POST] = true;
        $params[CURLOPT_POSTFIELDS] = $post_data;
        $params[CURLOPT_SSL_VERIFYPEER] = false;
        $params[CURLOPT_SSL_VERIFYHOST] = false;
        //以下是证书相关代码
        $params[CURLOPT_SSLCERTTYPE] = 'PEM';
        $params[CURLOPT_SSLCERT] = getcwd() . "/../cert/apiclient_cert.pem";//绝对路径
        $params[CURLOPT_SSLKEYTYPE] = 'PEM';
        $params[CURLOPT_SSLKEY] = getcwd() . "/../cert/apiclient_key.pem";//绝对路径

        curl_setopt_array($ch, $params); //传入curl参数
        $content = curl_exec($ch); //执行

        if ($content) {
            curl_close($ch);
            return $content;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            return false;
        }
    }

    /**
     * 计算两点之间的距离
     * @param $lng1 开始
     * @param $lat1 开始
     * @param $lng2 结束
     * @param $lat2 结束
     * @param int $unit m，km
     * @param int $decimal 位数
     * @return float
     */
    public static function getDistance($lng1, $lat1, $lng2, $lat2, $unit = 2, $decimal = 2)
    {

        $EARTH_RADIUS = 6370.996; // 地球半径系数
        $PI = 3.1415926535898;

        $radLat1 = $lat1 * $PI / 180.0;
        $radLat2 = $lat2 * $PI / 180.0;

        $radLng1 = $lng1 * $PI / 180.0;
        $radLng2 = $lng2 * $PI / 180.0;

        $a = $radLat1 - $radLat2;
        $b = $radLng1 - $radLng2;

        $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
        $distance = $distance * $EARTH_RADIUS * 1000;

        if ($unit === 2) {
            $distance /= 1000;
        }

        return round($distance, $decimal);
    }

    /**
     * 获取随机字符串
     * @param $len
     * @param null $chars
     * @return string
     */
    public static function getRandomString($len, $chars = null)
    {
        if (is_null($chars)) {
            $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        }
        mt_srand(10000000 * (double)microtime());
        for ($i = 0, $str = '', $lc = strlen($chars) - 1; $i < $len; $i++) {
            $str .= $chars[mt_rand(0, $lc)];
        }
        return $str;
    }

    /**
     * 计算星座
     * @param $birthday
     * @param null $format
     * @return mixed
     */
    public static function getConstellation($birthday, $format = null)
    {
        $date = explode('-', $birthday);
        $year = $date[0];
        $month = $date[1];
        $day = $date[2];
        if ($month < 1 || $month > 12 || $day < 1 || $day > 31) {
            return null;
        }
        //设定星座数组
        $constellations = ['摩羯座', '水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座'];

        //设定星座结束日期的数组，用于判断
        $enddays = array(19, 18, 20, 20, 20, 21, 22, 22, 22, 22, 21, 21,);
        //如果参数format被设置，则返回值采用format提供的数组，否则使用默认的数组
        if ($format != null) {
            $values = $format;
        } else {
            $values = $constellations;
        }
        //根据月份和日期判断星座
        switch ($month) {
            case 1:
                if ($day <= $enddays[0]) {
                    $constellation = $values[0];
                } else {
                    $constellation = $values[1];
                }
                break;
            case 2:
                if ($day <= $enddays[1]) {
                    $constellation = $values[1];
                } else {
                    $constellation = $values[2];
                }
                break;
            case 3:
                if ($day <= $enddays[2]) {
                    $constellation = $values[2];
                } else {
                    $constellation = $values[3];
                }
                break;
            case 4:
                if ($day <= $enddays[3]) {
                    $constellation = $values[3];
                } else {
                    $constellation = $values[4];
                }
                break;
            case 5:
                if ($day <= $enddays[4]) {
                    $constellation = $values[4];
                } else {
                    $constellation = $values[5];
                }
                break;
            case 6:
                if ($day <= $enddays[5]) {
                    $constellation = $values[5];
                } else {
                    $constellation = $values[6];
                }
                break;
            case 7:
                if ($day <= $enddays[6]) {
                    $constellation = $values[6];
                } else {
                    $constellation = $values[7];
                }
                break;
            case 8:
                if ($day <= $enddays[7]) {
                    $constellation = $values[7];
                } else {
                    $constellation = $values[8];
                }
                break;
            case 9:
                if ($day <= $enddays[8]) {
                    $constellation = $values[8];
                } else {
                    $constellation = $values[9];
                }
                break;
            case 10:
                if ($day <= $enddays[9]) {
                    $constellation = $values[9];
                } else {
                    $constellation = $values[10];
                }
                break;
            case 11:
                if ($day <= $enddays[10]) {
                    $constellation = $values[10];
                } else {
                    $constellation = $values[11];
                }
                break;
            case 12:
                if ($day <= $enddays[11]) {
                    $constellation = $values[11];
                } else {
                    $constellation = $values[0];
                }
                break;
        }
        return $constellation;
    }

    /**
     * 计算生肖
     * @param $birthday
     * @return mixed
     */
    public static function birthdayBornTag($birthday)
    {
        $year = substr($birthday, 0, 4);
        $bornTagarray = ['猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊'];
        $index = $year % 12;
        $bornTag = $bornTagarray[$index];
        return $bornTag;
    }

    /**
     * 计算年龄
     * @param $birthday
     * @return false|string
     */
    public static function getAge($birthday)
    {
        //格式化出生时间年月日
        list($byear, $bmonth, $bday) = explode('-', $birthday);
        //格式化当前时间年月日
        $tyear = date('Y');
        $tmonth = date('m');
        $tday = date('d');
        //开始计算年龄
        $age = $tyear - $byear;
        if ($bmonth > $tmonth || $bmonth == $tmonth && $bday > $tday) {
            $age--;
        }
        return $age;
    }

    /**
     * @param $birthday
     * @return array|string
     */
    public static function getAgeWeek($birthday)
    {
        $return_data = [
            'value' => 0,
            'unit' => '周'
        ];
        if (empty($birthday)) {
            return $return_data;
        }
        $time = strtotime($birthday);
        $len = time() - $time;
        if ($len < (365 * 24 * 3600) / 2) {
            $week = intval($len / (7 * 24 * 3600));
            $return_data = [
                'value' => $week,
                'unit' => '周'
            ];
            return $return_data;
        }
        if ($len > (365 * 24 * 3600) / 2 && $len < (365 * 24 * 3600)) {
            $return_data = [
                'value' => 0.5,
                'unit' => '岁'
            ];
            return $return_data;
        }
        //格式化出生时间年月日
        list($byear, $bmonth, $bday) = explode('-', $birthday);
        //格式化当前时间年月日
        $tyear = date('Y');
        $tmonth = date('m');
        $tday = date('d');
        //开始计算年龄
        $age = $tyear - $byear;
        if ($bmonth > $tmonth || $bmonth == $tmonth && $bday > $tday) {
            $age--;
        }
        $return_data = [
            'value' => $age,
            'unit' => '岁'
        ];
        return $return_data;
    }

    /**
     * 手机号格式检查
     * @param string $mobile
     * @return bool
     */
    public static function isMobileNumber($mobile)
    {
        if (!is_numeric($mobile)) {
            return false;
        }
        $reg = "/^1[0123456789]\d{9}$/";

        return preg_match($reg, $mobile) ? true : false;
    }

    /**
     * 手机号码打*
     * @param string $phone
     * @return string
     */
    public static function swPhoneStr($phone = '')
    {
        if (empty($phone)) {
            return "****";
        }
        $phone = substr($phone, 0, 3) . "****" . substr($phone, -3);
        return $phone;
    }

    /**
     * 获取富文本图片
     *
     * @param [type] $content
     * @return void
     */
    public static function getContentImgs($content)
    {
        $pattern = '/<img((?!src).)*src[\s]*=[\s]*[\'"](?<src>[^\'"]*)[\'"]/i';
        preg_match_all($pattern, $content, $matchContent);
        return $matchContent['src'];
    }

    /**
     * 比较两个数的大小 a>b 正数  小于负数 等于0
     * @param $a
     * @param $b
     * @return int
     */
    public static function getCompare($a, $b)
    {
        $status = "";
        if ($a > $b) {
            $status = "↑";
        }
        if ($a < $b) {
            $status = "↓";
        }
        return $status;
    }
}